查看原文
其他

Python之禅

Ahab Ahab杂货铺 2019-02-15

               点击上方“Ahab杂货铺”,选择“置顶公众号”

技术分享第一时间送达!


                                       

                                                                                                   


写在前面

什么样的程序是好的?如何编写漂亮的代码?这是学习编程一段时间最经常提出的问题,却难以回答。程序设计语言如同自然语言一样,好的代码就像文学作品,不仅意达,更要优美。那么什么是好?什么是优美?领悟编程代码优美的过程类似参禅,除了不断练习,也需要理解一些原则。

Python编译器以函数库的形式内置了一个有趣的文件,被称为“Python之禅”(The Zen of Python)。python之禅介绍了编写好代码的基本原则,今天就给大家介绍python之禅。


具体介绍

1import this

如果调用上面的一行语句后,就会出现一段有趣的运行结果。

1
2The Zen of Python, by Tim Peters
3
4Beautiful is better than ugly.
5Explicit is better than implicit.
6Simple is better than complex.
7Complex is better than complicated.
8Flat is better than nested.
9Sparse is better than dense.
10Readability counts.
11Special cases aren't special enough to break the rules.
12Although practicality beats purity.
13Errors should never pass silently.
14Unless explicitly silenced.
15In the face of ambiguity, refuse the temptation to guess.
16There should be one-- and preferably only one --obvious way to do it.
17Although that way may not be obvious at first unless you're Dutch.
18Now is better than never.
19Although never is often better than *right* now.
20If the implementation is hard to explain, it's a bad idea.
21If the implementation is easy to explain, it may be a good idea.
22Namespaces are one honking great idea -- let's do more of those!
23


这是一篇由Tim Peters撰写的文章,介绍了编写优美的Python程序所需要关注的一些重要原则,翻译成中文就是:

                                               

译文

优美胜于丑陋;

明了胜于晦涩;

简洁胜于复杂;

复杂胜于凌乱;

扁平胜于嵌套;

间隔胜于紧凑;

可读性很重要;

即便假借特例的实用性之名,也不可违背上述规则;

除非你确定需要,任何错误都应该有应对;

当存在多种可能,不要尝试去猜测;

只要你不是Guido,对于问题尽量找一种,最好是说唯一明显的解决方案;

做也许好过不做,但不假思索就动手还不如不做;

如果你无法向人描述你的实现方案,那肯定不是一个好方案;反之亦然;

命名空间是绝妙的理念,我们应当多加利用。


按照自己的理解将这个原则翻译成通俗易懂的白话就是:
Python 以编写优美的代码为目标,不要过多解释;
优美的代码应该是清晰明了,命名规范,风格相似;
优美的代码应该逻辑简洁,不要有复杂的内部实现;
如果必须采用复杂逻辑,那代码间也不能有难懂的关系,要保持接口简洁;
优美的代码应当是扁平的,不能有太多的嵌套;
优美的代码有适当的间隔,每行代码解决适当的问题;
优美的代码是可读且易读的;
这些规则至高无上;
精准地捕获异常,不写 except:pass 风格的代码,不让程序留有因错误退出的可能;
不要试图给出多种方案,找到一种实现他,你并没有python之父那么牛;
编程之前要思考;
能说清楚的往往是对的;
适合复杂程序编程。

比较恶搞的是,其实 this 模块的代码完全违背了这些原则,为了方便大家查看它的代码,我把它贴出来:
1s = """Gur Mra bs Clguba, ol Gvz Crgref
2
3Ornhgvshy vf orggre guna htyl.
4Rkcyvpvg vf orggre guna vzcyvpvg.
5Fvzcyr vf orggre guna pbzcyrk.
6Pbzcyrk vf orggre guna pbzcyvpngrq.
7Syng vf orggre guna arfgrq.
8Fcnefr vf orggre guna qrafr.
9Ernqnovyvgl pbhagf.
10Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf.
11Nygubhtu cenpgvpnyvgl orngf chevgl.
12Reebef fubhyq arire cnff fvyragyl.
13Hayrff rkcyvpvgyl fvyraprq.
14Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.
15Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.
16Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu.
17Abj vf orggre guna arire.
18Nygubhtu arire vf bsgra orggre guna *evtug* abj.
19Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn.
20Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.
21Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!"""

22
23d = {}
24for c in (6597):
25    for i in range(26):
26        d[chr(i+c)] = chr((i+13) % 26 + c)
27
28print (" ".join([d.get(c, c) for c in s]))

现在解析一下不符合原则的代码,第1到21行是一个字符串s,但是该字符串并非明文,是一种隐射加密。将s转换成明文内容的代码是从23行到28行,使用(i+13)%26把这些字母影射成明文每个字符往前移动了13位再模26(字母个数),例如B的ASCII值是66,移动13位即是66+13=79即字母O。char(65)代表字符‘A’,char(97)代表字符‘a’,那么24行到26行建立了字母a到z和字母A到Z的一个13位循移动的对应表,如下所示:
密文:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
原文:
NOPQRSTUVWXYZABCDEFGHIJKLM

                                                                        

写在最后

期待大家都能写出优美的代码,里边有些禅意我也没悟透,就是结合我自己的代码经验来写的,希望大牛斧正,这个原则不仅仅适用于python,对于java,c都是一样的。最后祝大家周末愉快




【推荐阅读】

Python面向对象之封装(04)

从0开始如何用一个月杀进机器学习比赛Top25%

30行代码实现微信自动回复机器人

【LeetCode】(No.020)有效的括号


欢迎您的点赞和分享

▲长按关注此公众号

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存